#include "Const.h"
#include "Util.h"
#include "Config.h"

Config* Config::m_instance = 0;

Config* Config::Instance()
{
	if (!m_instance) {
		m_instance = new Config();		
	}
	return m_instance;	
}

void Config::Init(const string& param)
{
	if(!m_init) {
		size_t pos = param.find_last_of("/");
		m_configFile = param.substr(0, pos+1) + C_STR_CONFIG;
		if (ReadConfig())
			++m_init;			
	}		
}

bool Config::ReadConfig()
{
	TiXmlDocument doc(m_configFile.c_str());			
	bool loadOkay = doc.LoadFile();
	if (!loadOkay) return false;

	TiXmlElement *rootElement;
	TiXmlElement *itemElement;
	rootElement = doc.RootElement();
	if (!rootElement) return false;

	itemElement = rootElement->FirstChildElement("num");
	if (!InitVecNum(itemElement)) return false;	

	itemElement = rootElement->FirstChildElement("insertion");
	if (!InitInsertion(itemElement)) return false;
	
	itemElement = rootElement->FirstChildElement("selection");
	if (!InitSelection(itemElement)) return false;
	
	itemElement = rootElement->FirstChildElement("swap");
	if (!InitSwap(itemElement)) return false;
	
	itemElement = rootElement->FirstChildElement("merge");
	if (!InitMerge(itemElement)) return false;
}

bool Config::InitVecNum(TiXmlElement* todoElement)
{
	if (!todoElement) return false;
	string strNum = todoElement->Attribute("item");	
	vector<string> vec;
	Util::Explode(strNum, vec);
	
	for(size_t i=0; i<vec.size(); ++i) {
		m_vecNum.push_back(atoi(vec[i].c_str()));
	}
	
	return true;
}

bool Config::InitInsertion(TiXmlElement* todoElement)
{
	if (!todoElement) return false;
	m_insertion.m_enable = atoi(todoElement->Attribute("enable"));	

	TiXmlElement* itemElement = todoElement->FirstChildElement("direct");
	if (!itemElement) return false;

	m_insertion.m_direct.m_enable = atoi(itemElement->Attribute("enable"));
	m_insertion.m_direct.m_iter = atoi(itemElement->Attribute("iter"));
	m_insertion.m_direct.m_recur = atoi(itemElement->Attribute("recur"));
	m_insertion.m_direct.m_print = atoi(itemElement->Attribute("print"));			 					
	
	itemElement = todoElement->FirstChildElement("binary");
	if (!itemElement) return false;

	m_insertion.m_binary.m_enable = atoi(itemElement->Attribute("enable"));
	m_insertion.m_binary.m_iter = atoi(itemElement->Attribute("iter"));
	m_insertion.m_binary.m_recur = atoi(itemElement->Attribute("recur"));
	m_insertion.m_binary.m_print = atoi(itemElement->Attribute("print"));			 					
	
	itemElement = todoElement->FirstChildElement("shell");
	if (!itemElement) return false;

	m_insertion.m_shell.m_enable = atoi(itemElement->Attribute("enable"));
	m_insertion.m_shell.m_iter = atoi(itemElement->Attribute("iter"));
	m_insertion.m_shell.m_recur = atoi(itemElement->Attribute("recur"));
	m_insertion.m_shell.m_print = atoi(itemElement->Attribute("print"));			 					

	return true;
}
   
bool Config::InitSelection(TiXmlElement* todoElement)
{
	if (!todoElement) return false;
	m_selection.m_enable = atoi(todoElement->Attribute("enable"));	

	TiXmlElement* itemElement = todoElement->FirstChildElement("simple");
	if (!itemElement) return false;

	m_selection.m_simple.m_enable = atoi(itemElement->Attribute("enable"));
	m_selection.m_simple.m_iter = atoi(itemElement->Attribute("iter"));
	m_selection.m_simple.m_recur = atoi(itemElement->Attribute("recur"));
	m_selection.m_simple.m_print = atoi(itemElement->Attribute("print"));			 					
	
	itemElement = todoElement->FirstChildElement("heap");
	if (!itemElement) return false;

	m_selection.m_heap.m_enable = atoi(itemElement->Attribute("enable"));
	m_selection.m_heap.m_iter = atoi(itemElement->Attribute("iter"));
	m_selection.m_heap.m_recur = atoi(itemElement->Attribute("recur"));
	m_selection.m_heap.m_print = atoi(itemElement->Attribute("print"));			 					
	
	return true;
}

bool Config::InitSwap(TiXmlElement* todoElement)
{
	if (!todoElement) return false;
	m_swap.m_enable = atoi(todoElement->Attribute("enable"));	

	TiXmlElement* itemElement = todoElement->FirstChildElement("bubble");
	if (!itemElement) return false;

	m_swap.m_bubble.m_enable = atoi(itemElement->Attribute("enable"));
	m_swap.m_bubble.m_iter = atoi(itemElement->Attribute("iter"));
	m_swap.m_bubble.m_recur = atoi(itemElement->Attribute("recur"));
	m_swap.m_bubble.m_print = atoi(itemElement->Attribute("print"));			 					
	
	itemElement = todoElement->FirstChildElement("quick");
	if (!itemElement) return false;

	m_swap.m_quick.m_enable = atoi(itemElement->Attribute("enable"));
	m_swap.m_quick.m_iter = atoi(itemElement->Attribute("iter"));
	m_swap.m_quick.m_recur = atoi(itemElement->Attribute("recur"));
	m_swap.m_quick.m_print = atoi(itemElement->Attribute("print"));			 					
	
	return true;
}
    
bool Config::InitMerge(TiXmlElement* todoElement)
{
	if (!todoElement) return false;
	m_merge.m_enable = atoi(todoElement->Attribute("enable"));	

	TiXmlElement* itemElement = todoElement->FirstChildElement("merge");
	if (!itemElement) return false;

	m_merge.m_merge.m_enable = atoi(itemElement->Attribute("enable"));
	m_merge.m_merge.m_iter = atoi(itemElement->Attribute("iter"));
	m_merge.m_merge.m_recur = atoi(itemElement->Attribute("recur"));
	m_merge.m_merge.m_print = atoi(itemElement->Attribute("print"));			 					

	return true;
}
